package com.hiecho;

import javassist.*;
import lombok.SneakyThrows;
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URL;

public class ClassLoadApp {
    @SneakyThrows
    public static void main(String[] args) {
        CustomizeClassLoad customiseClassLoad = new CustomizeClassLoad();
        Class<?> clazz = customiseClassLoad.loadClass("com.hiecho.javassist.entity.Apple");
        Object instance = clazz.newInstance();
//        Method hello1 = clazz.getMethod("hello1", Integer.class, Double.class);
//        hello1.invoke(instance,1,2);
        Method getValue = clazz.getMethod("getValue");
        Object invoke = getValue.invoke(instance, null);
        System.out.println(invoke);


    }

    @SneakyThrows
    @Test
    void test03() throws CannotCompileException, IOException {
 CustomizeClassLoad customiseClassLoad = new CustomizeClassLoad();
        Class<?> clazz = customiseClassLoad.loadClass("com.hiecho.javassist.entity.Apple");

        ClassPool cp = ClassPool.getDefault();

        Object instance = clazz.newInstance();
//        Method hello1 = clazz.getMethod("hello1", Integer.class, Double.class);
//        hello1.invoke(instance,1,2);
        Method getValue = clazz.getMethod("getValue");
        Object invoke = getValue.invoke(instance, null);
        System.out.println(invoke);


    }

    @SneakyThrows
    @Test
    void test02() throws CannotCompileException, IOException {

        URL resource = ClassLoadApp.class.getClassLoader().getResource("");
        String file = resource.getFile();
        System.out.println("文件存储路径：" + file);

        ClassPool cp = ClassPool.getDefault();
        CtClass ctClass = cp.makeClass("com.hiecho.entity.Apple");

        //添加一个int类型的，名字为value的变量
        CtField ctField = new CtField(CtClass.intType, "value", ctClass);
        ctField.setModifiers(Modifier.PRIVATE);
        ctClass.addField(ctField);

        //添加一个hello1的方法
        CtMethod ctMethod = new CtMethod(CtClass.voidType, "hello1", new CtClass[]{CtClass.intType, CtClass.doubleType}, ctClass);
        ctMethod.setModifiers(Modifier.PUBLIC);
//        ctMethod.insertBefore("System.out.println(\"我在前面插入了：\"+this.value);");
        ctMethod.setBody("this.value = $1 + $2;");
        ctMethod.insertBefore("System.out.println(\"我在前面插入了：\"+$1);");
        ctMethod.insertAfter("System.out.println(\"我在最后插入了：\"+$1);");
        ctClass.addMethod(ctMethod);


        //为value变量添加set方法
        CtMethod setValue = new CtMethod(CtClass.voidType, "setValue", new CtClass[]{CtClass.intType}, ctClass);
        setValue.setModifiers(Modifier.PUBLIC);
        //设置方法体
        setValue.setBody("this.value = $1;");
        setValue.insertBefore("System.out.println(\"我在前面插入了：\"+this.value);");
        ctMethod.setBody("System.out.println($args);");
        //设置方法体
        ctClass.addMethod(setValue);

        //为value变量添加get方法
        CtMethod getValue = new CtMethod(CtClass.intType, "getValue", new CtClass[]{}, ctClass);
        getValue.setModifiers(Modifier.PUBLIC);
        //设置方法体
//        ctMethod.setBody("System.out.println(this.value);");
        getValue.setBody("return this.value;");
        getValue.insertBefore("System.out.println(\"我在前面插入了：\"+this.value);");
//        getValue.insertAfter("System.out.println(\"我在最后插入了：\"+$1);");
        //设置方法体
        ctClass.addMethod(getValue);


        ctClass.writeFile(file);
    }
}
